Option Strict On
Option Explicit On 

Public Class Maskedbox
    Inherits System.Windows.Forms.TextBox

    Private mMask As String

    Protected Overrides Function IsInputKey(ByVal keyData As System.Windows.Forms.Keys) As Boolean
        'Select Case keyData
        '    Case Keys.Up, Keys.Down, Keys.Left, Keys.Right, Keys.Tab, CType(65545, Windows.Forms.Keys) : Return True
        'End Select
        Return True
    End Function

    Protected Overrides Sub OnKeyDown(ByVal e As System.Windows.Forms.KeyEventArgs)
        MyBase.OnKeyDown(e)
        On Error Resume Next

        If mMask <> "" Then
            Select Case e.KeyCode
                Case Keys.Delete
                    Dim txt As String = MyBase.Text
                    Dim sel As Integer = Me.SelectionStart

                    Dim selStart, selEnd As Integer
                    If Me.SelectionLength = 0 Then
                        If Me.SelectionStart < MyBase.Text.Length Or Me.SelectionStart < Me.mMask.Length Then
                            selStart = Me.SelectionStart
                            selEnd = selStart
                        Else
                            selStart = 1
                            selEnd = 0
                        End If
                    Else
                        selStart = Me.SelectionStart
                        selEnd = selStart + Me.SelectionLength - 1
                    End If

                    Dim i As Integer
                    For i = selEnd To selStart Step -1
                        If i < mMask.Length Then
                            If i < txt.Length Then txt = txt.Remove(i, 1)
                            sel += 1

                            Dim msk As String = mMask.Substring(i, 1)
                            If msk = "#" Or msk = "&" Then
                                txt = txt.Insert(i, "_")
                            Else
                                txt = txt.Insert(i, msk)
                            End If
                        Else
                            If i < txt.Length Then txt = txt.Remove(i, 1)
                        End If
                    Next

                    e.Handled = True

                    MyBase.Text = txt
                    Me.SelectionStart = sel
            End Select
        End If
    End Sub
    Protected Overrides Sub OnKeyPress(ByVal e As System.Windows.Forms.KeyPressEventArgs)
        MyBase.OnKeyPress(e)
        On Error Resume Next

        If mMask <> "" Then
            Dim txt As String = MyBase.Text
            Dim sel As Integer = Me.SelectionStart

            If Asc(e.KeyChar) = 8 Then
                Dim selStart, selEnd As Integer
                If Me.SelectionLength = 0 Then
                    If Me.SelectionStart > 0 Then
                        selStart = Me.SelectionStart - 1
                        selEnd = selStart
                        sel -= 1
                    End If
                Else
                    selStart = Me.SelectionStart
                    selEnd = selStart + Me.SelectionLength - 1
                End If

                Dim i As Integer
                For i = selEnd To selStart Step -1
                    If i < mMask.Length Then
                        txt = txt.Remove(i, 1)

                        Dim msk As String = mMask.Substring(i, 1)
                        If msk = "#" Or msk = "&" Then
                            txt = txt.Insert(i, "_")
                        Else
                            txt = txt.Insert(i, msk)
                        End If
                    Else
                        txt = txt.Remove(i, 1)
                    End If
                Next

                e.Handled = True

                MyBase.Text = txt
                Me.SelectionStart = sel
                Me.SelectionLength = 0
            ElseIf Char.IsControl(e.KeyChar) Then
            Else
                Dim i As Integer
                For i = Me.SelectionStart To MyBase.Text.Length
                    If i < mMask.Length Then
                        Dim msk As String = mMask.Substring(i, 1)
                        If msk = "#" Then
                            If Char.IsDigit(e.KeyChar) Then
                                If i < txt.Length Then txt = txt.Remove(i, 1)
                                txt = txt.Insert(i, e.KeyChar.ToString)
                                sel += 1
                            Else
                                Beep()
                            End If
                            Exit For
                        ElseIf msk = "&" Then
                            If i < txt.Length Then txt = txt.Remove(i, 1)
                            txt = txt.Insert(i, e.KeyChar.ToString)
                            sel += 1
                            Exit For
                        Else
                            If i < txt.Length Then txt = txt.Remove(i, 1)
                            txt = txt.Insert(i, msk)
                            sel += 1
                        End If
                    Else
                        Beep()
                        Exit For
                    End If
                Next

                e.Handled = True

                MyBase.Text = txt
                Me.SelectionStart = sel
                Me.SelectionLength = 0
            End If
        End If
    End Sub

    Public Property Mask() As String
        Get
            Return mMask
        End Get

        Set(ByVal Value As String)
            If Value Is Nothing Then
                mMask = Value
            Else
                mMask = Value.Trim

                'Dim txt As String = mMask
                'txt = txt.Replace("#", "_")
                'txt = txt.Replace("&", "_")
                'Mybase.Text = txt
            End If
        End Set
    End Property
    Public Function CheckMask() As Boolean
        CheckMask = True
        If mMask <> "" Then
            Dim txt As String = mMask
            txt = txt.Replace("#", "_")
            txt = txt.Replace("&", "_")

            If MyBase.Text <> txt Then
                If mMask.Length = MyBase.Text.Length Then
                    Dim i As Integer
                    For i = 0 To mMask.Length - 1
                        Dim msk As String = mMask.Substring(i, 1)
                        Select Case msk
                            Case "#"
                                If Not IsNumeric(MyBase.Text.Substring(i, 1)) Then Return False
                            Case "&"
                                If MyBase.Text.Substring(i, 1) = "_" Then Return False
                            Case Else
                                If MyBase.Text.Substring(i, 1) <> msk Then Return False
                        End Select
                    Next
                Else
                    Return False
                End If
            End If
        End If
    End Function
    'Public Function GetText() As String
    '    If mMask = "" Then
    '        Return MyBase.Text
    '    Else
    '        Dim txt As String = mMask
    '        txt = txt.Replace("#", "_")
    '        txt = txt.Replace("&", "_")

    '        If MyBase.Text = txt Then
    '            Return ""
    '        Else
    '            Return MyBase.Text
    '        End If
    '    End If
    'End Function
    'Public Sub SetText(ByVal value As String)
    '    If mMask = "" Then
    '        MyBase.Text = value
    '    Else
    '        If value = "" Then
    '            Dim txt As String = mMask
    '            txt = txt.Replace("#", "_")
    '            txt = txt.Replace("&", "_")

    '            MyBase.Text = txt
    '        Else
    '            MyBase.Text = value
    '        End If
    '    End If
    'End Sub
    Public Function Length() As Integer
        Return MyBase.Text.Length
    End Function
    Public Overrides Property Text() As String
        Get
            If mMask = "" Then
                Return MyBase.Text
            Else
                Dim txt As String = mMask
                txt = txt.Replace("#", "_")
                txt = txt.Replace("&", "_")

                If MyBase.Text = txt Then
                    Return ""
                Else
                    Return MyBase.Text
                End If
            End If
        End Get
        Set(ByVal Value As String)
            If mMask = "" Then
                MyBase.Text = Value
            Else
                If Value = "" Then
                    Dim txt As String = mMask
                    txt = txt.Replace("#", "_")
                    txt = txt.Replace("&", "_")

                    MyBase.Text = txt
                Else
                    MyBase.Text = Value
                End If
            End If
        End Set
    End Property

    Public Sub New()
        MyBase.New()
    End Sub
End Class
